package cn.okcode.slowjson.parser;

import cn.okcode.slowjson.JsonArray;
import cn.okcode.slowjson.JsonObject;
import cn.okcode.slowjson.ast.*;
import cn.okcode.slowjson.internal.JsonException;

import java.util.List;
import java.util.Map;
import java.util.Stack;

/**
 * 将json字符串转换JsonArray或者JsonObject
 *
 * @author pyk13
 */
public final class DefaultDeSerializeVisitorImpl implements Visitor {
    private JsonArray listValue;
    private JsonObject mapValue;

    private final Stack<Object> valueStack;

    public DefaultDeSerializeVisitorImpl() {
        this.valueStack = new Stack<>();
    }

    @Override
    public void visit(ArrayNode node) {
        JsonArray values = new JsonArray();
        for (AbstractNode<?> childNode : node.getElements()) {
            childNode.accept(this);
            Object value = valueStack.pop();
            values.add(value);
        }
        valueStack.push(values);
    }

    @Override
    public void visit(BoolNode node) {
        valueStack.push(node.getValue());
    }

    @Override
    public void visit(NullNode node) {
        valueStack.push(node.getValue());
    }

    @Override
    public void visit(NumberNode node) {
        valueStack.push(node.getValue());
    }

    @Override
    public void visit(ObjectNode node) {
        JsonObject properties = new JsonObject();
        for (Map.Entry<PropertyNode, AbstractNode<?>> entry : node.getProperties().entrySet()) {

            String key = entry.getKey().getValue();
            AbstractNode<?> valueNode = entry.getValue();

            //这里不能直接使用valueNode.getValue()，因为valueNode可能是数组或者对象节点，不能直接获取值
            valueNode.accept(this);

            Object value = valueStack.pop();
            properties.put(key, value);
        }
        valueStack.push(properties);
    }

    @Override
    public void visit(StringNode node) {
        valueStack.push(node.getValue());
    }

    @Override
    public void visit(PropertyNode node) {
        //什么都不做
    }

    /**
     * 获取JsonObject对象，相当于Map
     *
     * @return Map
     */
    @SuppressWarnings("unchecked")
    public JsonObject getJsonObject() {
        if (mapValue == null) {
            Object value = valueStack.pop();
            if (value instanceof Map) {
                mapValue = new JsonObject(((Map) value).size());
                mapValue.putAll((Map) value);
            } else {
                throw new JsonException("转换类型不匹配");
            }
        }
        return mapValue;
    }

    /**
     * 获取JsonArray对象，相当于List
     *
     * @return List集合
     */
    public JsonArray getJsonArray() {
        if (listValue == null) {
            Object value = valueStack.pop();
            if (value instanceof List) {
                List<?> list = (List<?>) value;
                listValue = new JsonArray(list.size());
                listValue.addAll(list);
            } else {
                throw new JsonException("转换类型不匹配");
            }
        }
        return listValue;
    }
}
